/*   TIMER.C/H - copyright (c) Toni R„s„nen, 1998
 *   --------------------------------------------
 *   Routines to use PIT-timer.
 *
 *
 *   Files required: TIMER.C, TIMER.H
 *
 *   Revision history:
 *       02.07.98: Original code
 *
 *
 */


#include <go32.h>
#include <dpmi.h>
#include "timer.h"

_go32_dpmi_seginfo timer_oldint,timinfo;
volatile long long timer_originalcall;
volatile int timerdel,timerinc;
timerPFV timer_routine;

static volatile void timerint_lockbeg() {}

void timer_null_function() {}

void timerint_function()
{
   if (timer_routine)
     timer_routine();
   timerdel += timerinc;
   if (timerdel >= 1000)
     {  __asm__ __volatile ("pushfl
                             lcall %0"
                            :
                            : "g" (timer_originalcall) );
        timerdel -= 1000;
     }
   else
     {  outportb (0x20,0x20); }
}

static volatile void timerint_lockend() {}



void set_pit(int count)
{  timerinc = 18200 / count;
   timerdel = 0;
   count = 1192755 / count;

   outportb (0x43, 0x36);
   outportb (0x40, count & 0xff);
   outportb (0x40, count >> 8);
}

void close_timers()
{  _go32_dpmi_set_protected_mode_interrupt_vector(0x08, &timer_oldint);
   outportb (0x43, 0x36);
   outportb (0x40, 0);
   outportb (0x40, 0);
}

void init_timers()
{
   _go32_dpmi_lock_code(timerint_lockbeg,((unsigned)timerint_lockend-(unsigned)timerint_lockbeg+1) );

   timer_routine = timer_null_function;

   _go32_dpmi_get_protected_mode_interrupt_vector(0x08, &timer_oldint);
   timer_originalcall = ((unsigned long long)timer_oldint.pm_offset) +
                        (((unsigned long long)timer_oldint.pm_selector)<<32);


   timinfo.pm_offset=(unsigned long int)timerint_function;
   timinfo.pm_selector=_my_cs();
   _go32_dpmi_allocate_iret_wrapper(&timinfo);
   _go32_dpmi_set_protected_mode_interrupt_vector(0x08, &timinfo);
}


